{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "mncPcdFCmU-7"
   },
   "source": [
    "# Jupyter Notebook - Ransomware report use cases 1\n",
    "\n",
    "Copyright © 2021 Google\n",
    "\n",
    "Welcome to our Ransomware in a Global Context Jupyter notebook!\n",
    "\n",
    "You can find this and other very interesting posts in our [blog](https://blog.virustotal.com/)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "id": "fQ8iCKRpo_mu"
   },
   "outputs": [],
   "source": [
    "#@markdown Please, insert your VT API Key*:\n",
    "\n",
    "API_KEY = ''  #@param  {type: \"string\"}\n",
    "\n",
    "#@markdown **The API key should have Premium permissions, otherwise some of the use cases might not provide the expected results.*\n",
    "\n",
    "#@markdown \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "62mNyWJ-0_J_"
   },
   "source": [
    "\n",
    "\n",
    "---\n",
    "---\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "yZYLFG3kAB_a"
   },
   "outputs": [],
   "source": [
    "!pip install vt-py nest_asyncio"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "qqOSPhLwsRLT"
   },
   "source": [
    "# Use Case: Distribution vectors extraction\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "tioTJg2cGu4v"
   },
   "source": [
    "\n",
    "Given a couple of searches like these ones:\n",
    "\n",
    "       engines:gandcrab fs:2020-02-01+ fs:2020-05-01- (type:peexe or type:pedll) tag:exploit (have:compressed_parents OR have:execution_parents OR have:pcap_parents OR have:email_parents)\n",
    "       engines:gandcrab fs:2020-02-01+ fs:2020-05-01- (type:peexe or type:pedll) have:in_the_wild\n",
    "\n",
    "You can easily extract the distribution vectors of those matches thanks to the different relationships related to those observables. More concretely, we are going to focus on these relationships:\n",
    "\n",
    "*   [itw_ips](https://docs.virustotal.com/reference/itw_ips)\n",
    "*   [itw_urls](https://docs.virustotal.com/reference/files-itw_urls)\n",
    "*   [itw_domains](https://docs.virustotal.com/reference/files-itw_domains)\n",
    "*   [compressed_parents](https://docs.virustotal.com/reference/files-compressed_parents)\n",
    "*   [execution_parents](https://docs.virustotal.com/reference/files-execution_parents)\n",
    "*   [pcap_parents](https://docs.virustotal.com/reference/files-pcap_parents)\n",
    "*   [email_parents](https://docs.virustotal.com/reference/files-email_parents)\n",
    "\n",
    "Please note that as the search is looking for old files, the **retrospection's limitation** that you might have can affect to the number of results that this report provides.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "b2EfBIOAGULg"
   },
   "source": [
    "## Workflow:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "4zz5GQlCGFvU"
   },
   "source": [
    "![distribution_vector_flow.png]()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "JTFRE4n6G8BJ"
   },
   "source": [
    "## Script:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "65bz9z8Tvbka"
   },
   "outputs": [],
   "source": [
    "import base64\n",
    "import hashlib\n",
    "import json\n",
    "import requests\n",
    "\n",
    "QUERIES = [\n",
    "    \"engines:gandcrab fs:2020-02-01+ fs:2020-05-01- (type:peexe or type:pedll) tag:exploit (have:compressed_parents OR have:execution_parents OR have:pcap_parents OR have:email_parents)\",\n",
    "    \"engines:gandcrab fs:2020-02-01+ fs:2020-05-01- (type:peexe or type:pedll) have:in_the_wild\"\n",
    "]\n",
    "RELATIONSHIPS = [\"itw_ips\", \"itw_urls\", \"itw_domains\", \"compressed_parents\", \"execution_parents\", \"pcap_parents\", \"email_parents\"]\n",
    "separator = \",\"\n",
    "RELATIONSHIPS_URL = separator.join(RELATIONSHIPS)\n",
    "detected_domains = {}\n",
    "detected_ips = {}\n",
    "detected_urls = {}\n",
    "detected_files = {}\n",
    "analyzed_objects = []\n",
    "\n",
    "\n",
    "def get_search_results(query, vt_client):\n",
    "  \"\"\"Execute the search and return the results.\"\"\"\n",
    "  url = \"/intelligence/search\"\n",
    "  results = vt_client.iterator(url, params={\"query\": query, \"relationships\": RELATIONSHIPS_URL})\n",
    "  \n",
    "  return results\n",
    "\n",
    "\n",
    "def analyse_observable(observable, observable_type, vt_client):\n",
    "  if observable not in analyzed_objects:\n",
    "    observable_report = get_observable_report(observable,observable_type, vt_client)\n",
    "    if observable_report:\n",
    "      extract_iocs(observable, observable_type, vt_client, observable_report)\n",
    "  else:\n",
    "    extract_iocs(observable, observable_type, vt_client)\n",
    "\n",
    "\n",
    "def get_observable_report(observable, observable_type, vt_client):\n",
    "  \"\"\"Get the observable's intelligence report from VirusTotal.\"\"\"\n",
    "\n",
    "  endpoint = {\"url\": \"urls\", \"domain\": \"domains\", \"ip_address\": \"ip_addresses\", \"file\": \"files\"}\n",
    "  if observable_type == \"url\":\n",
    "    observable = base64.urlsafe_b64encode(observable.encode()).decode().strip(\"=\")   \n",
    "  endpoint = endpoint[observable_type]\n",
    "  if observable_type == \"file\":\n",
    "    results = vt_client.get_object(f\"/{endpoint}/{observable}?relationships={RELATIONSHIPS_URL}\")\n",
    "  else:\n",
    "    results = vt_client.get_object(f\"/{endpoint}/{observable}?relationships=votes\")\n",
    "  return results\n",
    "\n",
    "\n",
    "\n",
    "def add_observable(iocs_dict, observable, positives=False):\n",
    "  \"\"\"Check if the observable was already seen before adding it into the final report.\"\"\"\n",
    "\n",
    "  if observable not in iocs_dict:\n",
    "    iocs_dict[observable] = {}\n",
    "    iocs_dict[observable][\"positives\"] = positives\n",
    "    iocs_dict[observable][\"relatives\"] = 1\n",
    "  else:\n",
    "    iocs_dict[observable][\"relatives\"] += 1\n",
    "\n",
    "  if observable not in analyzed_objects:\n",
    "    analyzed_objects.append(observable)\n",
    "  return iocs_dict\n",
    "\n",
    "\n",
    "def extract_iocs(observable, observable_type, vt_client, observable_report=False):\n",
    "  \"\"\"Add the malicious relationships into the list of detected ovservables.\"\"\"\n",
    "\n",
    "  global detected_ips\n",
    "  global detected_urls\n",
    "  global detected_domains\n",
    "  global detected_files\n",
    "\n",
    "  if observable_report:\n",
    "    positives = observable_report.last_analysis_stats[\"malicious\"]\n",
    "  else:\n",
    "    try:\n",
    "      positives = detected_files[observable][\"positives\"]\n",
    "    except:\n",
    "      positives = False\n",
    "  if observable_type == \"ip_address\":\n",
    "    detected_ips = add_observable(detected_ips, observable, positives)\n",
    "  elif observable_type == \"url\":\n",
    "    detected_urls = add_observable(detected_urls, observable, positives)\n",
    "  elif observable_type == \"domain\":\n",
    "    detected_domains = add_observable(detected_domains, observable, positives)\n",
    "  else:\n",
    "    detected_files = add_observable(detected_files, observable, positives)\n",
    "    if detected_files[observable][\"relatives\"] == 1:\n",
    "      search_and_hunt(vt_client, observable_report)\n",
    "  return\n",
    "\n",
    "\n",
    "def search_and_hunt(vt_client, observable_report=False):\n",
    "  \"\"\"Iterate over the queries and get matches.\n",
    "\n",
    "    Then, analyze the relationships of those matches.\n",
    "  \"\"\"\n",
    "\n",
    "  if observable_report:\n",
    "    results = observable_report\n",
    "    for relationship in RELATIONSHIPS:\n",
    "      if results.relationships[relationship][\"data\"]:\n",
    "        for hit in results.relationships[relationship][\"data\"]:\n",
    "          observable_type = hit[\"type\"]\n",
    "          observable = hit[\"id\"]\n",
    "          if observable_type == \"url\":\n",
    "            observable = hit[\"context_attributes\"][\"url\"]\n",
    "          analyse_observable(observable, observable_type, vt_client)\n",
    "\n",
    "\n",
    "  else:\n",
    "    for query in QUERIES:\n",
    "        results = get_search_results(query, vt_client)\n",
    "        for result in results:\n",
    "          match = result.id\n",
    "          for relationship in RELATIONSHIPS:\n",
    "            if result.relationships[relationship][\"data\"]:\n",
    "              for hit in result.relationships[relationship][\"data\"]:\n",
    "                observable_type = hit[\"type\"]\n",
    "                observable = hit[\"id\"]\n",
    "                if observable_type == \"url\":\n",
    "                  observable = hit[\"context_attributes\"][\"url\"]\n",
    "                analyse_observable(observable, observable_type, vt_client) \n",
    "\n",
    "\n",
    "def print_report():\n",
    "  \"\"\"Iterate over the detected observables and print the results.\"\"\"\n",
    "\n",
    "  def print_header():\n",
    "    row = [\"Positives\",\"Relatives\",\"VT Link\",\"Observable\"]\n",
    "    print(\"{: ^15} {: <15} {: ^20} {: >100}\".format(*row))\n",
    "    print(\"_\"*200)\n",
    "\n",
    "  def print_dict(d,type):\n",
    "    d2 = {}\n",
    "    for item in d:\n",
    "      d2[item] = d[item][\"relatives\"]\n",
    "\n",
    "    top_view = [ (v,k) for k,v in d2.items() ]\n",
    "    top_view.sort(reverse=True)\n",
    "\n",
    "    for items in top_view:\n",
    "      observable = items[1]\n",
    "      if type == \"url\":\n",
    "        encoded_url = hashlib.sha256(items[1].encode()).hexdigest()\n",
    "        row = [d[observable][\"positives\"],d[observable][\"relatives\"],\"https://www.virustotal.com/gui/\" + type + \"/\"+encoded_url,observable]\n",
    "      else:\n",
    "        row = [d[observable][\"positives\"],d[observable][\"relatives\"],\"https://www.virustotal.com/gui/\" + type + \"/\"+observable,observable]\n",
    "      print(\"{: ^10} {:^17} {: <110} {: <70}\".format(*row))\n",
    "\n",
    "  print(\"\\n\\tDISTRIBUTION VECTORS REPORT\\n\")\n",
    "\n",
    "  print(\"\\n#1: FILES\\n\")\n",
    "  print_header()\n",
    "  print_dict(detected_files, \"file\")\n",
    "\n",
    "  print(\"\\n##2: DOMAINS\\n\")\n",
    "  print_header()\n",
    "  print_dict(detected_domains, \"domain\")\n",
    "\n",
    "  print(\"\\n#3: URLS\\n\")\n",
    "  print_header()\n",
    "  print_dict(detected_urls, \"url\")\n",
    "\n",
    "  print(\"\\n#4: IP ADDRESSES\\n\")\n",
    "  print_header()\n",
    "  print_dict(detected_ips, \"ip-address\")\n",
    "\n",
    "  print(\"\\n\")\n",
    "\n",
    "\n",
    "def main():\n",
    "  vt_client = vt.Client(API_KEY)\n",
    "  search_and_hunt(vt_client)\n",
    "  print_report()\n",
    "\n",
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "MMHJja5CpXiU"
   },
   "source": [
    "# Use Case: Ports and IP extraction\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "O3LCTVZGO6ot"
   },
   "source": [
    "In this use case we are going to focus on the lateral movements prevention. \n",
    "\n",
    "In order to this we will make use of the behavioural network reports."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "7D8S__2oQJUV"
   },
   "source": [
    "![IP_Traffic.png]()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "UQCjoXlfO-D0"
   },
   "source": [
    "## Script:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "3ZS5-7SZOqgr"
   },
   "outputs": [],
   "source": [
    "import nest_asyncio\n",
    "nest_asyncio.apply()\n",
    "import base64\n",
    "import requests\n",
    "import vt\n",
    "\n",
    "QUERIES = [\n",
    "    \"engines:gandcrab fs:2020-02-01+ fs:2020-05-01- (type:peexe or type:pedll) tag:exploit have:behaviour_network\"\n",
    "]\n",
    "RELATIONSHIPS = [\"behaviours\"]\n",
    "separator = \",\"\n",
    "RELATIONSHIPS_URL = separator.join(RELATIONSHIPS)\n",
    "extractions = {}\n",
    "verdicts = {}\n",
    "analyzed_objects = []\n",
    "\n",
    "\n",
    "def get_search_results(query, vt_client):\n",
    "  \"\"\"Execute the search and return the results.\"\"\"\n",
    "  url = \"/intelligence/search\"\n",
    "  results = vt_client.iterator(url, params={\"query\": query, \"relationships\": RELATIONSHIPS_URL})\n",
    "  \n",
    "  return results\n",
    "\n",
    "def analyse_observable(observable, observable_type, vt_client):\n",
    "  if observable not in analyzed_objects:\n",
    "    analyzed_objects.append(observable)\n",
    "    observable_report = get_observable_report(observable, observable_type, vt_client)\n",
    "    if observable_report:\n",
    "      extract_iocs(observable, observable_report, vt_client)\n",
    "\n",
    "\n",
    "def get_observable_report(observable, observable_type, vt_client):\n",
    "  \"\"\"Get the observable's intelligence report from VirusTotal.\"\"\"\n",
    "\n",
    "  endpoint = {\"file_behaviour\": \"file_behaviours\", \"ip_address\": \"ip_addresses\"}\n",
    "  endpoint = endpoint[observable_type]\n",
    "  results = vt_client.get_object(f\"/{endpoint}/{observable}\")\n",
    "  return results\n",
    "\n",
    "\n",
    "def extract_iocs(observable, observable_report, vt_client):\n",
    "  \"\"\"Add the malicious relationships into the list of detected ovservables.\"\"\"\n",
    "\n",
    "  global extractions\n",
    "  global verdicts\n",
    "\n",
    "  if hasattr(observable_report, \"ip_traffic\"):\n",
    "    comms = observable_report.ip_traffic\n",
    "\n",
    "    for comm in comms:\n",
    "      try:\n",
    "        protocol = comm[\"transport_layer_protocol\"]\n",
    "      except:\n",
    "        protocol = \"Unknown\"\n",
    "      ip = comm[\"destination_ip\"]\n",
    "      port = comm[\"destination_port\"]\n",
    "      hash = observable[:64]\n",
    "\n",
    "      if hash not in extractions:\n",
    "        extractions[hash] = {\"ports\":[], \"ips\":[], \"protocols\":[]}\n",
    "      if port not in extractions[hash][\"ports\"]:\n",
    "        extractions[hash][\"ports\"].append(port)\n",
    "        verdicts[port] = \"N/A\"\n",
    "      if ip not in extractions[hash][\"ips\"]:\n",
    "        extractions[hash][\"ips\"].append(ip)\n",
    "        if \"DNS\" in ip:\n",
    "          positives = \"N/A\"\n",
    "        else:\n",
    "          observable_report = get_observable_report(ip, \"ip_address\", vt_client)\n",
    "          positives = observable_report.last_analysis_stats[\"malicious\"]\n",
    "        verdicts[ip] = positives\n",
    "      if protocol not in extractions[hash][\"protocols\"]:\n",
    "        extractions[hash][\"protocols\"].append(protocol)\n",
    "        verdicts[protocol] = \"N/A\"\n",
    "\n",
    "  return\n",
    "\n",
    "\n",
    "def search_and_hunt(vt_client):\n",
    "  for query in QUERIES: \n",
    "    results = get_search_results(query, vt_client)\n",
    "    for result in results:\n",
    "      match = result.id\n",
    "      for relationship in RELATIONSHIPS:\n",
    "        if result.relationships[relationship][\"data\"]:\n",
    "          for hit in result.relationships[relationship][\"data\"]:\n",
    "            observable_type = hit[\"type\"]\n",
    "            observable = hit[\"id\"]\n",
    "            analyse_observable(observable, observable_type, vt_client)\n",
    "\n",
    "\n",
    "def print_report():\n",
    "  elements = [\"ports\", \"ips\", \"protocols\"]\n",
    "  for e in elements:\n",
    "    get_top_list(e)\n",
    "\n",
    "\n",
    "def get_top_list(element):\n",
    "  e_list = []\n",
    "  for hash in extractions:\n",
    "    e_list = list(set(e_list) | set(extractions[hash][element]))\n",
    "\n",
    "  e_top = {}\n",
    "  for hash in extractions:\n",
    "    for e in e_list:\n",
    "      if e not in e_top:\n",
    "        e_top[e] = 0\n",
    "      if e in extractions[hash][element]:\n",
    "        e_top[e] += 1\n",
    "\n",
    "  print(\"\\nTOP \" + element + \"\\n\" + \"_\"*100 + \"\\n\")\n",
    "  top_view = [ (v,k) for k,v in e_top.items() ]\n",
    "  top_view.sort(reverse=True)\n",
    "  for matches,observable in top_view:\n",
    "      row = [str(verdicts[observable]), observable, \"Number of matches: \", matches]\n",
    "      print(\"\\tPositives: {: >8} {: ^20} {: >20} {: >3}\".format(*row))\n",
    "\n",
    "\n",
    "def main():\n",
    "  vt_client = vt.Client(API_KEY)\n",
    "  search_and_hunt(vt_client)\n",
    "  print_report()\n",
    "\n",
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "IZwKMdcipRrq"
   },
   "source": [
    "# Use Case: Geographical Distribution"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "IGexVXLUUJ77"
   },
   "source": [
    "In this use case we will iterate over all the matches of our initial search:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "cellView": "form",
    "id": "HB38UKRKr64G"
   },
   "outputs": [],
   "source": [
    "#@markdown\n",
    "\n",
    "VTI_SEARCH = 'engines:gandcrab fs:2020-02-01+ fs:2020-05-01- (type:peexe or type:pedll) tag:exploit'  #@param  {type: \"string\"}\n",
    "\n",
    "#@markdown "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "fE9GTrt-r_hM"
   },
   "source": [
    "The difference now is that we will take a look to the Submissions tab in order to indentify how this malware has been spread around the world."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "U5Q5HcuJULBa"
   },
   "source": [
    "![Submissions.png]()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Wyls5rGZUNk7"
   },
   "source": [
    "## Script:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "XocPGaF-URFT"
   },
   "outputs": [],
   "source": [
    "import nest_asyncio\n",
    "nest_asyncio.apply()\n",
    "import json\n",
    "import requests\n",
    "import vt\n",
    "\n",
    "QUERIES = [\n",
    "    VTI_SEARCH\n",
    "]\n",
    "RELATIONSHIPS = [\"submissions\"]\n",
    "separator = \",\"\n",
    "RELATIONSHIPS_URL = separator.join(RELATIONSHIPS)\n",
    "countries = {}\n",
    "cities = {}\n",
    "\n",
    "\n",
    "def get_submission(id, vt_client):\n",
    "  results = vt_client.get_object(f\"/submissions/{id}\")\n",
    "  interface = results.interface\n",
    "  if interface == \"email\":\n",
    "    return False, False, interface\n",
    "  country = results.country\n",
    "  if country == \"ZZ\":\n",
    "    city = country\n",
    "  else:\n",
    "    city = results.city\n",
    "  return country, city, interface\n",
    "\n",
    "def get_search_results(query, vt_client):\n",
    "  \"\"\"Execute the search and return the results.\"\"\"\n",
    "  url = \"/intelligence/search\"\n",
    "  results = vt_client.iterator(url, params={\"query\": query, \"relationships\": RELATIONSHIPS_URL})\n",
    "  \n",
    "  return results\n",
    "\n",
    "\n",
    "\n",
    "def print_report():\n",
    "  print(\"\\nTOP targeted countries\\n\" + \"_\"*100 + \"\\n\")\n",
    "\n",
    "  countries_view = [ (v,k) for k,v in countries.items() ]\n",
    "  countries_view.sort(reverse=True)\n",
    "  for submission,country in countries_view:\n",
    "    row = [country,\"Number of submissions: \",submission]\n",
    "    print(\"{: >15} {: >25} {: >2}\".format(*row))\n",
    "\n",
    "  print(\"\\nTOP targeted cities\\n\" + \"_\"*100 + \"\\n\")\n",
    "\n",
    "  cities_view = [ (v,k) for k,v in cities.items() ]\n",
    "  cities_view.sort(reverse=True)\n",
    "  for submission,city in cities_view:\n",
    "    row = [city,\"Number of submissions: \",submission]\n",
    "    print(\"{: >35} {: >25} {: >2}\".format(*row))\n",
    "\n",
    "def search_and_hunt(vt_client):\n",
    "  global countries\n",
    "  global cities\n",
    "\n",
    "  for query in QUERIES:\n",
    "      results = get_search_results(query, vt_client)\n",
    "      for result in results:       \n",
    "        positives = result.last_analysis_stats[\"malicious\"]\n",
    "        for hit in result.relationships[\"submissions\"][\"data\"]:\n",
    "          submission_id = hit[\"id\"]\n",
    "          country,city,interface = get_submission(submission_id, vt_client)\n",
    "\n",
    "          if interface != \"email\":\n",
    "            if country not in countries:\n",
    "              countries[country] = 0\n",
    "            countries[country] += 1\n",
    "            if city not in cities:\n",
    "              cities[city] = 0\n",
    "            cities[city] += 1\n",
    "\n",
    "\n",
    "def main():\n",
    "  vt_client = vt.Client(API_KEY)\n",
    "  search_and_hunt(vt_client)\n",
    "  print_report()\n",
    "\n",
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "mMOyXrZoOY1P"
   },
   "source": [
    "# Use Case: TOP vulnerabilities"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "9qd-rECmOh2J"
   },
   "source": [
    "In this use case we are going to extract the top exploited vulnerabilities given an intelligence search like the one below:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "cellView": "form",
    "id": "RgEuPEvln72E"
   },
   "outputs": [],
   "source": [
    "#@markdown\n",
    "\n",
    "VTI_SEARCH = 'engines:gandcrab fs:2020-02-01+ fs:2020-05-01- (type:peexe or type:pedll) tag:exploit'  #@param  {type: \"string\"}\n",
    "\n",
    "#@markdown "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "OBivUmbkPF6j"
   },
   "source": [
    "## Script:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "2yunHaXDO2DS"
   },
   "outputs": [],
   "source": [
    "import nest_asyncio\n",
    "nest_asyncio.apply()\n",
    "import json\n",
    "import requests\n",
    "import vt\n",
    "\n",
    "QUERIES = [\n",
    "    VTI_SEARCH\n",
    "]\n",
    "cve_tags = {}\n",
    "\n",
    "\n",
    "def get_search_results(query, vt_client):\n",
    "  \"\"\"Execute the search and return the results.\"\"\"\n",
    "  url = \"/intelligence/search\"\n",
    "  results = vt_client.iterator(url, params={\"query\": query})\n",
    "  \n",
    "  return results\n",
    "\n",
    "\n",
    "def search_and_hunt(vt_client):\n",
    "  global cve_tags\n",
    "\n",
    "  for query in QUERIES:\n",
    "    results = get_search_results(query, vt_client)\n",
    "    for result in results:\n",
    "      for tag in getattr(result, \"tags\", []):\n",
    "        if \"cve\" in tag:\n",
    "          if tag not in cve_tags:\n",
    "            cve_tags[tag] = 0\n",
    "          cve_tags[tag] += 1\n",
    "\n",
    "def print_report():\n",
    "  print(\"\\nTOP Vulnerabilities\" + \"\\n\" + \"_\"*100 + \"\\n\")\n",
    "  top_view = [ (v,k) for k,v in cve_tags.items() ]\n",
    "  top_view.sort(reverse=True)\n",
    "  for v,k in top_view:\n",
    "      row = [k,\"Number of matches: \",v]\n",
    "      print(\"{: >15} {: >25} {: >5}\".format(*row))\n",
    "\n",
    "def main():\n",
    "  vt_client = vt.Client(API_KEY)\n",
    "  search_and_hunt(vt_client)\n",
    "  print_report()\n",
    "\n",
    "main()"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "collapsed_sections": [],
   "name": "Ransomware in a global context vt-py.ipynb",
   "provenance": [],
   "toc_visible": true
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
